package com.liulu.window.insets

import android.app.Activity
import android.graphics.Color
import android.os.Build
import android.util.Log
import android.view.Window
import android.view.WindowManager
import androidx.annotation.ColorInt
import androidx.core.view.OnApplyWindowInsetsListener
import androidx.core.view.ViewCompat
import androidx.core.view.WindowCompat
import androidx.core.view.WindowInsetsCompat
import androidx.core.view.WindowInsetsControllerCompat

private const val TAG = "WindowInsetsUnits"

private fun log(msg: String) {
    if (BuildConfig.DEBUG) {
        Log.d(TAG, msg)
    }
}

/**
 * 设置状态栏颜色（非沉浸式有效，ViewCompat.setOnApplyWindowInsetsListener后无效）
 *
 * @param statusBarColor
 */
fun Activity?.setStatusBarColor(@ColorInt statusBarColor: Int = Color.TRANSPARENT) {
    val window: Window? = this?.window
    if (window == null) {
        log("window is null")
        return
    }
    window.statusBarColor = statusBarColor
}

/**
 * 设置导航栏颜色（非沉浸式有效，ViewCompat.setOnApplyWindowInsetsListener后无效）
 *
 * @param navigationBarColor
 * @param navigationBarDividerColor
 */
fun Activity?.setNavigationBarColor(
    @ColorInt navigationBarColor: Int = Color.TRANSPARENT,
    @ColorInt navigationBarDividerColor: Int = Color.TRANSPARENT
) {
    val window: Window? = this?.window
    if (window == null) {
        log("window is null")
        return
    }
    window.navigationBarColor = navigationBarColor
    if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.P) {
        window.navigationBarDividerColor = navigationBarDividerColor
    }
}

/**
 * 设置状态栏和导航栏字体或图标颜色
 *
 * @param statusBarBlack     true白底黑字，false黑底白字
 * @param navigationBarBlack true白底黑字，false黑底白字
 */
fun Activity?.setAppearanceLightBars(
    statusBarBlack: Boolean = true,
    navigationBarBlack: Boolean = true
) {
    val window: Window? = this?.window
    if (window == null) {
        log("window is null")
        return
    }
    val controller = WindowCompat.getInsetsController(window, window.decorView)
    //浅色模式(light)，白底黑字
    //深色模式(dark)，黑底白字
    controller.isAppearanceLightStatusBars = statusBarBlack
    controller.isAppearanceLightNavigationBars = navigationBarBlack
}

/**
 * 设置状态栏和导航栏反差遮罩
 * ```
 * 在Android 10以上，当设置了导航栏背景为透明时，isNavigationBarContrastEnforced如果为true，则系统会自动绘制一个半透明背景来提供对比度
 * ```
 * @param statusBarContrast
 * @param navigationBarContrast
 */
fun Activity?.setContrastEnforcedBars(
    statusBarContrast: Boolean = false,
    navigationBarContrast: Boolean = false
) {
    val window: Window? = this?.window
    if (window == null) {
        log("window is null")
        return
    }
    if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.Q) {
        //默认false
        window.isStatusBarContrastEnforced = statusBarContrast
        //默认true
        window.isNavigationBarContrastEnforced = navigationBarContrast
    }
}

/**
 * 沉浸式
 *
 * @param barType
 * @param statusBarBlack        true白底黑字，false黑底白字
 * @param navigationBarBlack    true白底黑字，false黑底白字
 */
fun Activity?.immerse(
    @BarType barType: Int = BarType.NORMAL,
    statusBarBlack: Boolean = true,
    navigationBarBlack: Boolean = true
) {
    if (this == null) {
        log("Activity is null")
        return
    }
    val window: Window? = this.window
    if (window == null) {
        log("window is null")
        return
    }
    if (barType !in BarType.NORMAL..BarType.NAVIGATION) {
        log("barType not in BarType.NORMAL..BarType.NAVIGATION")
        return
    }
    //沉浸式：使用状态栏和导航栏区域，必须设置false
    WindowCompat.setDecorFitsSystemWindows(window, false)
    val decorView = window.decorView
    val controller = WindowCompat.getInsetsController(window, decorView)
    //浅色模式(light)，白底黑字
    //深色模式(dark)，黑底白字
    controller.isAppearanceLightStatusBars = statusBarBlack
    controller.isAppearanceLightNavigationBars = navigationBarBlack

    //在Android 10以上，当设置了导航栏栏背景为透明时，isNavigationBarContrastEnforced如果为true，则系统会自动绘制一个半透明背景来提供对比度
    if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.Q) {
        //默认false
        window.isStatusBarContrastEnforced = false
        //默认true
        window.isNavigationBarContrastEnforced = false
    }

    val lp = window.attributes
    //使用异形区域
    //default全屏窗口不会使用到刘海区域，非全屏窗口可正常使用刘海区
    //shortEdges窗口始终允许延伸到屏幕短边上的DisplayCutout区域
    //never窗口不允许和刘海屏重叠
    //always窗口始终允许延伸到屏幕所有边缘的DisplayCutout区域
    if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.R) {
        lp.layoutInDisplayCutoutMode =
            WindowManager.LayoutParams.LAYOUT_IN_DISPLAY_CUTOUT_MODE_ALWAYS
    } else if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.P) {
        lp.layoutInDisplayCutoutMode =
            WindowManager.LayoutParams.LAYOUT_IN_DISPLAY_CUTOUT_MODE_SHORT_EDGES
    }
    window.setAttributes(lp)

    ViewCompat.setOnApplyWindowInsetsListener(decorView) { v, insets ->
        val systemBars = insets.getInsets(WindowInsetsCompat.Type.systemBars())
        log("left: " + systemBars.left + "，top: " + systemBars.top + "，right: " + systemBars.right + "，bottom: " + systemBars.bottom)
        when (barType) {
            BarType.ALL -> {
                log("allBar")
                v.setPadding(0, 0, 0, 0)
            }

            BarType.STATUS -> {
                log("statusBar")
                v.setPadding(0, 0, 0, systemBars.bottom)
            }

            BarType.NAVIGATION -> {
                log("navigationBar")
                v.setPadding(0, systemBars.top, 0, 0)
            }

            else -> {
                v.setPadding(
                    systemBars.left,
                    systemBars.top,
                    systemBars.right,
                    systemBars.bottom
                )
            }
        }
        insets
    }
}

fun Activity?.immerse(
    statusBarBlack: Boolean = true,
    navigationBarBlack: Boolean = true,
    listener: OnApplyWindowInsetsListener? = null
) {
    if (this == null) {
        log("Activity is null")
        return
    }
    val window: Window? = this.window
    if (window == null) {
        log("window is null")
        return
    }
    //沉浸式：使用状态栏和导航栏区域，必须设置false
    WindowCompat.setDecorFitsSystemWindows(window, false)
    val decorView = window.decorView
    val controller = WindowCompat.getInsetsController(window, decorView)
    //浅色模式(light)，白底黑字
    //深色模式(dark)，黑底白字
    controller.isAppearanceLightStatusBars = statusBarBlack
    controller.isAppearanceLightNavigationBars = navigationBarBlack

    //在Android 10以上，当设置了导航栏栏背景为透明时，isNavigationBarContrastEnforced如果为true，则系统会自动绘制一个半透明背景来提供对比度
    if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.Q) {
        //默认false
        window.isStatusBarContrastEnforced = false
        //默认true
        window.isNavigationBarContrastEnforced = false
    }

    val lp = window.attributes
    //使用异形区域
    //default全屏窗口不会使用到刘海区域，非全屏窗口可正常使用刘海区
    //shortEdges窗口始终允许延伸到屏幕短边上的DisplayCutout区域
    //never窗口不允许和刘海屏重叠
    //always窗口始终允许延伸到屏幕所有边缘的DisplayCutout区域
    if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.R) {
        lp.layoutInDisplayCutoutMode =
            WindowManager.LayoutParams.LAYOUT_IN_DISPLAY_CUTOUT_MODE_ALWAYS
    } else if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.P) {
        lp.layoutInDisplayCutoutMode =
            WindowManager.LayoutParams.LAYOUT_IN_DISPLAY_CUTOUT_MODE_SHORT_EDGES
    }
    window.setAttributes(lp)

    ViewCompat.setOnApplyWindowInsetsListener(decorView, listener)
}

/**
 * 全屏
 */
fun Activity?.hideSystemUI() {
    if (this == null) {
        log("Activity is null")
        return
    }
    val window: Window? = this.window
    if (window == null) {
        log("window is null")
        return
    }
    //沉浸式：使用状态栏和导航栏区域，必须设置false
    WindowCompat.setDecorFitsSystemWindows(window, false)
    val decorView = window.decorView
    val controller = WindowCompat.getInsetsController(window, decorView)
    controller.hide(WindowInsetsCompat.Type.systemBars())
    controller.systemBarsBehavior =
        WindowInsetsControllerCompat.BEHAVIOR_SHOW_TRANSIENT_BARS_BY_SWIPE
}

/**
 * 退出全屏
 */
fun Activity?.showSystemUI() {
    if (this == null) {
        log("Activity is null")
        return
    }
    val window: Window? = this.window
    if (window == null) {
        log("window is null")
        return
    }
    //沉浸式：使用状态栏和导航栏区域，必须设置false
    WindowCompat.setDecorFitsSystemWindows(window, false)
    val decorView = window.decorView
    val controller = WindowCompat.getInsetsController(window, decorView)
    controller.show(WindowInsetsCompat.Type.systemBars())
}
